home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / WindowLib / WindowEventLib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-14  |  7.8 KB  |  269 lines  |  [TEXT/KAHL]

  1. /* Window event functions.
  2.     
  3.     94/01/14 aih
  4.     - removed unneeded focus flag from WinRegister
  5.     - added focus field to window's extra data handle
  6.     
  7.     94/01/12 aih
  8.     - added functions for getting and setting event tables
  9.     
  10.     93/12/16 aih
  11.     - split out of EventUtilLib.c
  12.     
  13.     93/10/16 aih
  14.     - WinRegister/WinUnregister and WinTabRegister/WinTabUnregister have
  15.     no effect if we're not dealing with a window for which WinExtra would
  16.     return true. this allows using some of the library code (e.g., ListLib)
  17.     with windows not created by the libraries, such as customized directory
  18.     dialog boxes.
  19. */
  20.  
  21. #include "ArrayListLib.h"
  22. #include "EventPrivateLib.h"
  23. #include "MathLib.h"
  24. #include "MemoryLib.h"
  25. #include "RectangleLib.h"
  26. #include "WindowLib.h"
  27.  
  28. /*----------------------------------------------------------------------------*/
  29. /* getting and setting the window's focus */
  30. /*----------------------------------------------------------------------------*/
  31.  
  32. /* return the object in the window with the focus */
  33. EventType *WinFocus(WindowPtr window)
  34. {
  35.     return(window ? WinExtraPtr(window)->focus : NULL);
  36. }
  37.  
  38. /* set the window's focus object */
  39. void WinFocusSet(WindowPtr window, EventObjectType object)
  40. {
  41.     if (object != WinFocus(window)->object) {
  42.         EventType *focus = EventFindObject(WinObjects(window), object);
  43.         WinExtraPtr(window)->focus = focus;
  44.     }
  45.     ensure(object ? object == WinFocus(window)->object : ! WinFocus(window));
  46. }
  47.  
  48. /*----------------------------------------------------------------------------*/
  49. /* registering objects */
  50. /*----------------------------------------------------------------------------*/
  51.  
  52. /* return the first object in the window's object list */
  53. EventType *WinObjects(WindowPtr window)
  54. {
  55.     return(window ? WinExtraPtr(window)->objects : NULL);
  56. }
  57.  
  58. /* Register the object as belonging to the window. The object is inserted
  59.     at the head of the window's event list. */
  60. void WinRegister(WindowPtr window, EventObjectType object,
  61.     const EventTableType *table)
  62. {
  63.     if (WinHasExtra(window)) {
  64.         EventType *objects = EventInsert(WinExtraPtr(window)->objects, object, table);
  65.         WinExtraPtr(window)->objects = objects;
  66.     }
  67. }
  68.  
  69. /* remove the object from the window's event list */
  70. void WinUnregister(WindowPtr window, EventObjectType object)
  71. {
  72.     EventType *objects;
  73.     
  74.     if (window && WinHasExtra(window)) {
  75.         if (object == WinFocus(window))
  76.             WinFocusSet(window, NULL);
  77.         objects = EventDelete(WinExtraPtr(window)->objects, object);
  78.         WinExtraPtr(window)->objects = objects;
  79.     }
  80. }
  81.  
  82. /* assign the id to the object */
  83. void WinRegisterID(WindowPtr window, EventObjectType object, EventIDType id)
  84. {
  85.     EventType *list = EventFindObject(WinExtraPtr(window)->objects, object);
  86.     if (list) list->id = id;
  87. }
  88.  
  89. /* return the object with the specified ID */
  90. EventObjectType WinRegisteredID(WindowPtr window, EventIDType id)
  91. {
  92.     EventType *item = EventFindID(WinExtraPtr(window)->objects, id);
  93.     return(item ? item->object : NULL);
  94. }
  95.  
  96. /*----------------------------------------------------------------------------*/
  97. /* getting and setting an object's event table */
  98. /*----------------------------------------------------------------------------*/
  99.  
  100. /* return the object's event table */
  101. const EventTableType *WinObjectTable(WindowPtr window, EventObjectType object)
  102. {
  103.     EventType *list;
  104.     
  105.     list = EventFindObject(WinExtraPtr(window)->objects, object);
  106.     return(list ? list->table : NULL);
  107. }
  108.  
  109. /* set the object's event table */
  110. void WinObjectTableSet(WindowPtr window, EventObjectType object,
  111.     const EventTableType *table)
  112. {
  113.     EventType *list;
  114.     
  115.     list = EventFindObject(WinExtraPtr(window)->objects, object);
  116.     if (list)
  117.         list->table = table;
  118. }
  119.  
  120. /*----------------------------------------------------------------------------*/
  121. /* window tab list */
  122. /*----------------------------------------------------------------------------*/
  123.  
  124. /* window's tab-able object list is a handle to an array of event objects */
  125. typedef EventType *TabListType;
  126. typedef TabListType *TabListPtr, **TabListHandle;
  127.  
  128. /* get the window's tab key object list */
  129. static ArrayListHandle WinTabList(WindowPtr window)
  130. {
  131.     return(WinExtraPtr(window)->tablist);
  132. }
  133.  
  134. /* set the window's tab list */
  135. static void WinTabListSet(WindowPtr window, ArrayListHandle tablist)
  136. {
  137.     ArrayListEnd(WinExtraPtr(window)->tablist);
  138.     WinExtraPtr(window)->tablist = tablist;
  139. }
  140.  
  141. /* return number of items in window's tab list */
  142. static short WinTabListCount(WindowPtr window)
  143. {
  144.     return(WinTabList(window) ? ArrayListCount(WinTabList(window)) : 0);
  145. }
  146.  
  147. /* true if window has a tab list with more than one object, and
  148.     so those objects (like lists) should draw bold outlines and
  149.     hitting the tab key should switch between objects */
  150. Boolean WinHasTabList(WindowPtr window)
  151. {
  152.     return(WinTabListCount(window) > 1);
  153. }
  154.  
  155. /* append the object to the window's tab list */
  156. void WinTabRegister(WindowPtr window, EventObjectType object)
  157. {
  158.     ArrayListHandle list;
  159.     EventType *event;
  160.     
  161.     if (WinHasExtra(window)) {
  162.         event = EventFindObject(WinObjects(window), object);
  163.         check(event != NULL);
  164.         if (! WinTabList(window))
  165.             WinTabListSet(window, ArrayListBegin(sizeof(TabListType)));
  166.         list = WinTabList(window);
  167.         ArrayListInsert(list, ArrayListCount(list));
  168.         ArrayListSet(list, ArrayListCount(list) - 1, &event);
  169.     }
  170. }
  171.  
  172. /* remove the object from the window's tab list */
  173. void WinTabUnregister(WindowPtr window, EventObjectType object)
  174. {
  175.     TabListHandle array;
  176.     short i, nitems;
  177.     
  178.     if (window && WinHasExtra(window)) {
  179.         nitems = WinTabListCount(window);
  180.         array = ArrayListGetHandle(WinTabList(window));
  181.         for (i = 0; i < nitems && (*array)[i]->object != object; i++)
  182.             ;
  183.         if (i < nitems) {
  184.             check(EventFindObject(WinObjects(window), object) != NULL);
  185.             ArrayListDelete(WinTabList(window), i);
  186.         }
  187.     }
  188. }
  189.  
  190. /* switch to next object in window's tab list */
  191. void WinTab(WindowPtr window)
  192. {
  193.     TabListHandle array;
  194.     EventType *focus;
  195.     short i, nitems;
  196.     
  197.     /* find object with current focus in window's tab list */
  198.     require(WinHasTabList(window));
  199.     focus = WinFocus(window);
  200.     nitems = WinTabListCount(window);
  201.     array = ArrayListGetHandle(WinTabList(window));
  202.     for (i = 0; i < nitems && (*array)[i] != focus; i++)
  203.         ;
  204.     if (i < nitems) {
  205.         /* select next object */
  206.         focus = (*array)[(i + 1) % nitems];
  207.         if (focus->table->focusWindow.selectall)
  208.             focus->table->focusWindow.selectall(focus->object);
  209.         FocusSet(focus->object);
  210.     }
  211. }
  212.  
  213. /*----------------------------------------------------------------------------*/
  214. /* resizing windows */
  215. /*----------------------------------------------------------------------------*/
  216.  
  217. /* Get the minimum and maximum size of the window by polling every
  218.     object in the window and merging the minimum and maximum sizes
  219.     returned by the objects. */
  220. void WinSizeRect(WindowPtr window, Rect *minmax)
  221. {
  222.     EventType *list;
  223.  
  224.     minmax->top = minmax->left = 20;
  225.     minmax->bottom = minmax->right = SHRT_MAX;
  226.     for (list = WinObjects(window); list; list = EventNext(list)) {
  227.         if (list->table->window.grow) {
  228.             Rect size = *minmax;
  229.             list->table->window.grow(list->object, &size);
  230.             minmax->top = max(minmax->top, size.top);
  231.             minmax->left = max(minmax->left, size.left);
  232.             minmax->bottom = min(minmax->bottom, size.bottom);
  233.             minmax->right = min(minmax->right, size.right);
  234.         }
  235.     }
  236. }
  237.  
  238. /* get the window's preferred width and height */
  239. void WinSizePreferred(WindowPtr window, short *width, short *height)
  240. {
  241.     Rect portRect;
  242.     EventType *list;
  243.  
  244.     WinPortRect(window, &portRect);
  245.     *width = *height = 20;
  246.     for (list = WinObjects(window); list; list = EventNext(list)) {
  247.         if (list->table->window.zoom) {
  248.             short w = RectWidth(&portRect);
  249.             short h = RectHeight(&portRect);
  250.             list->table->window.zoom(list->object, &w, &h);
  251.             *width = max(*width, w);
  252.             *height = max(*height, h);
  253.         }
  254.     }
  255. }
  256.  
  257. /* resize the objects in the window */
  258. void WinResize(WindowPtr window, short dh, short dv)
  259. {
  260.     EventType *list;
  261.  
  262.     if (dh != 0 || dv != 0) {
  263.         for (list = WinObjects(window); list; list = EventNext(list)) {
  264.             if (list->table->window.resize)
  265.                 list->table->window.resize(list->object, dh, dv);
  266.         }
  267.     }
  268. }
  269.